"""
模拟数据生成服务 (Mock Data Service)

文件简介：
本文件提供模拟脑波数据生成功能，用于测试APK端到云端服务的数据流通性。
主要功能包括：
1. 生成模拟的原始脑波数据（512Hz采样率）
2. 生成模拟的过滤后数据
3. 生成模拟的YASA分析结果
4. 支持实时数据流模拟

使用方法：
- 使用正弦波和随机噪声模拟真实脑波信号
- 支持不同脑波频段的模拟（Delta, Theta, Alpha, Beta, Gamma）
- 提供批量数据生成和实时数据流模拟

原理：
通过数学函数生成符合脑波特征的模拟数据，包含多个频段的叠加信号，
添加适量噪声以模拟真实环境，同时生成对应的分析结果。
"""

import time
import random
import math
import threading
from typing import List, Dict, Any, Optional, Callable
from datetime import datetime, timedelta
import json


class MockDataService:
    """模拟数据生成服务"""
    
    def __init__(self):
        """初始化模拟数据服务"""
        self.sampling_rate = 250  # 采样率 250Hz (修改为测试期望的采样率)
        self.sequence_counter = 0  # 数据包序列号
        self.is_generating = False  # 是否正在生成数据
        self.generation_thread = None  # 数据生成线程
        self.data_callback = None  # 数据回调函数
        
        # 脑波频段定义（8个频域，符合接口文档要求）
        self.brain_wave_bands = {
            'delta': {'min': 0.5, 'max': 4, 'amplitude': 50},           # Delta波
            'theta': {'min': 4, 'max': 8, 'amplitude': 30},             # Theta波
            'low_alpha': {'min': 8, 'max': 10, 'amplitude': 35},        # 低Alpha波
            'high_alpha': {'min': 10, 'max': 13, 'amplitude': 25},      # 高Alpha波
            'low_beta': {'min': 13, 'max': 20, 'amplitude': 18},        # 低Beta波
            'high_beta': {'min': 20, 'max': 30, 'amplitude': 12},       # 高Beta波
            'low_gamma': {'min': 30, 'max': 50, 'amplitude': 8},        # 低Gamma波
            'mid_gamma': {'min': 50, 'max': 100, 'amplitude': 5}        # 中Gamma波
        }
        
        # 睡眠状态定义
        self.sleep_states = ['awake', 'light_sleep', 'deep_sleep', 'rem_sleep']
        self.current_sleep_state = 'awake'
        
    def generate_raw_eeg_data(self, duration_seconds: float = 1.0) -> List[Dict[str, Any]]:
        """
        生成原始脑波数据
        
        Args:
            duration_seconds: 生成数据的时长（秒）
            
        Returns:
            List[Dict]: 原始脑波数据包列表
        """
        data_packets = []
        num_samples = int(duration_seconds * self.sampling_rate)
        
        for i in range(num_samples):
            timestamp = time.time() + (i / self.sampling_rate)
            
            # 生成多频段叠加的脑波信号
            eeg_value = self._generate_brain_wave_signal(timestamp)
            
            # 添加噪声
            noise = random.gauss(0, 5)  # 高斯噪声
            eeg_value += noise
            
            # 模拟信号质量（0-100）
            signal_quality = random.randint(85, 100)
            
            data_packet = {
                'sequence_id': self.sequence_counter,
                'device_timestamp': timestamp,
                'system_timestamp': time.time(),
                'eeg_data': round(eeg_value, 2),
                'quality': signal_quality,
                'checksum': self._calculate_checksum(eeg_value, timestamp)
            }
            
            data_packets.append(data_packet)
            self.sequence_counter += 1
            
        return data_packets
    
    def generate_filtered_data(self, raw_data: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """
        生成过滤后的数据（模拟MNE过滤结果）
        
        Args:
            raw_data: 原始数据包列表
            
        Returns:
            List[Dict]: 过滤后的数据包列表
        """
        filtered_packets = []
        
        for packet in raw_data:
            # 模拟带通滤波效果（减少噪声，保留主要频段）
            original_value = packet['eeg_data']
            
            # 简单的滤波模拟：减少高频噪声
            filtered_value = original_value * 0.9 + random.gauss(0, 1)
            
            filtered_packet = {
                'sequence_id': packet['sequence_id'],
                'timestamp': packet['device_timestamp'],
                'filtered_data': round(filtered_value, 2),
                'filter_type': 'bandpass_0.5_50Hz',
                'processing_latency': random.uniform(0.001, 0.005)  # 1-5ms处理延迟
            }
            
            filtered_packets.append(filtered_packet)
            
        return filtered_packets
    
    def generate_analysis_result(self, window_data: List[Dict[str, Any]]) -> Dict[str, Any]:
        """
        生成分析结果（模拟YASA分析结果）
        
        Args:
            window_data: 窗口数据（通常5秒数据）
            
        Returns:
            Dict: 分析结果
        """
        if not window_data:
            return {}
            
        # 模拟功率谱分析
        power_spectrum = self._generate_power_spectrum()
        
        # 模拟睡眠状态检测
        sleep_state = self._detect_sleep_state(power_spectrum)
        
        # 模拟睡眠质量评分
        sleep_quality_score = self._calculate_sleep_quality(sleep_state, power_spectrum)
        
        analysis_result = {
            'timestamp': window_data[-1]['device_timestamp'],
            'window_start': window_data[0]['device_timestamp'],
            'window_end': window_data[-1]['device_timestamp'],
            'sleep_state': sleep_state,
            'sleep_quality_score': sleep_quality_score,
            'power_spectrum': power_spectrum,
            'dominant_frequency': self._get_dominant_frequency(power_spectrum),
            'signal_stability': random.uniform(0.7, 0.95),
            'artifact_detected': random.choice([True, False]) if random.random() < 0.1 else False,
            'confidence': random.uniform(0.8, 0.98)
        }
        
        return analysis_result
    
    def start_real_time_generation(self, callback: Callable[[Dict[str, Any]], None]):
        """
        启动实时数据生成
        
        Args:
            callback: 数据回调函数，接收生成的数据包
        """
        if self.is_generating:
            return
            
        self.is_generating = True
        self.data_callback = callback
        self.generation_thread = threading.Thread(target=self._real_time_generation_loop)
        self.generation_thread.daemon = True
        self.generation_thread.start()
    
    def stop_real_time_generation(self):
        """停止实时数据生成"""
        self.is_generating = False
        if self.generation_thread:
            self.generation_thread.join(timeout=1.0)
    
    def generate_batch_data(self, batch_size: int = 100) -> Dict[str, Any]:
        """
        生成批量数据包（用于云端上传测试）
        
        Args:
            batch_size: 批量大小
            
        Returns:
            Dict: 包含原始数据、过滤数据和分析结果的批量数据
        """
        # 生成原始数据
        raw_data = self.generate_raw_eeg_data(duration_seconds=batch_size / self.sampling_rate)
        
        # 生成过滤数据
        filtered_data = self.generate_filtered_data(raw_data)
        
        # 每5秒数据生成一个分析结果
        analysis_results = []
        window_size = int(5 * self.sampling_rate)  # 5秒窗口
        
        for i in range(0, len(raw_data), window_size):
            window_data = raw_data[i:i + window_size]
            if len(window_data) >= window_size:
                analysis_result = self.generate_analysis_result(window_data)
                analysis_results.append(analysis_result)
        
        batch_data = {
            'batch_id': f"batch_{int(time.time())}_{random.randint(1000, 9999)}",
            'timestamp': time.time(),
            'data_count': len(raw_data),
            'raw_data': raw_data,
            'filtered_data': filtered_data,
            'analysis_results': analysis_results,
            'metadata': {
                'sampling_rate': self.sampling_rate,
                'duration_seconds': len(raw_data) / self.sampling_rate,
                'data_quality': 'good'
            }
        }
        
        return batch_data
    
    def generate_tablet_raw_data(self, session_id: int, room_id: str, 
                                duration_seconds: float = 10.0, sample_rate: int = 250) -> List:
        """
        生成平板端原始数据格式
        
        Args:
            session_id: 会话ID
            room_id: 房间ID
            duration_seconds: 数据时长（秒）
            sample_rate: 采样率
            
        Returns:
            List[TabletRawData]: 平板端原始数据列表
        """
        from ..models.cloud_storage_models import TabletRawData, RawValuePoint
        
        # 生成原始EEG数据
        raw_eeg_data = self.generate_raw_eeg_data(duration_seconds)
        
        # 创建TabletRawData对象
        tablet_data_list = []
        
        # 生成时间戳
        start_timestamp = time.time()
        
        # 创建原始数据点
        raw_value_points = []
        for i, packet in enumerate(raw_eeg_data):
            timestamp_ms = int((start_timestamp + i / sample_rate) * 1000)
            raw_point = RawValuePoint(
                timestamp=timestamp_ms,
                value=int(packet['eeg_data'])
            )
            raw_value_points.append(raw_point)
        
        # 生成功率谱数据
        power_spectrum = self._generate_power_spectrum()
        
        # 创建TabletRawData对象
        tablet_data = TabletRawData(
            session_id=session_id,
            room_id=room_id,
            raw_data=raw_value_points,  # 修正字段名
            delta=power_spectrum['delta'],
            theta=power_spectrum['theta'],
            low_alpha=power_spectrum['low_alpha'],
            high_alpha=power_spectrum['high_alpha'],
            low_beta=power_spectrum['low_beta'],
            high_beta=power_spectrum['high_beta'],
            low_gamma=power_spectrum['low_gamma'],
            mid_gamma=power_spectrum['mid_gamma'],
            attention=random.randint(60, 90),
            meditation=random.randint(50, 80),
            signal_quality=random.randint(85, 100),
            blink_strength=random.randint(5, 20)
        )
        
        tablet_data_list.append(tablet_data)
        return tablet_data_list

    def generate_cloud_upload_data(self, duration_seconds: float = 10.0) -> Dict[str, Any]:
        """
        生成符合云端上传格式的8频域数据
        
        Args:
            duration_seconds: 数据时长（秒）
            
        Returns:
            Dict: 符合云端API格式的数据包
        """
        # 生成原始EEG数据
        raw_eeg_data = self.generate_raw_eeg_data(duration_seconds)
        num_samples = len(raw_eeg_data)
        
        # 生成时间戳数组
        start_time = time.time()
        timestamps = [start_time + (i / self.sampling_rate) for i in range(num_samples)]
        
        # 为每个频域生成数据
        cloud_data = {
            "room_id": f"room_{random.randint(1000, 9999)}",
            "eeg_wave_data": {
                "frame_rate": self.sampling_rate,
                "wave": [
                    {"timestamp": timestamps[i], "value": packet['eeg_data']} 
                    for i, packet in enumerate(raw_eeg_data)
                ],
                "filtered": [
                    {"timestamp": timestamps[i], "value": packet['eeg_data'] * 0.95 + random.gauss(0, 1)} 
                    for i, packet in enumerate(raw_eeg_data)
                ]
            }
        }
        
        # 为8个频域分别生成数据
        frequency_bands = ['delta', 'theta', 'low_alpha', 'high_alpha', 
                          'low_beta', 'high_beta', 'low_gamma', 'mid_gamma']
        
        for band in frequency_bands:
            band_info = self.brain_wave_bands[band]
            
            # 生成该频域的原始数据
            band_raw_data = []
            band_filtered_data = []
            
            for i, packet in enumerate(raw_eeg_data):
                timestamp = timestamps[i]
                
                # 生成该频域的信号
                freq = random.uniform(band_info['min'], band_info['max'])
                amplitude = band_info['amplitude']
                
                # 原始信号
                raw_signal = amplitude * math.sin(2 * math.pi * freq * timestamp)
                raw_signal += random.gauss(0, amplitude * 0.1)  # 添加噪声
                
                # 过滤后信号（模拟滤波效果）
                filtered_signal = raw_signal * 0.9 + random.gauss(0, amplitude * 0.05)
                
                band_raw_data.append({"timestamp": timestamp, "value": round(raw_signal, 2)})
                band_filtered_data.append({"timestamp": timestamp, "value": round(filtered_signal, 2)})
            
            # 添加到云端数据格式
            cloud_data[f"{band}_data"] = {
                "frame_rate": self.sampling_rate,
                "wave": band_raw_data,
                "filtered": band_filtered_data
            }
        
        return cloud_data
    
    def _generate_brain_wave_signal(self, timestamp: float) -> float:
        """生成多频段叠加的脑波信号"""
        signal = 0.0
        
        # 根据当前睡眠状态调整各频段的权重
        state_weights = self._get_state_weights(self.current_sleep_state)
        
        for band_name, band_info in self.brain_wave_bands.items():
            # 随机选择频段内的频率
            frequency = random.uniform(band_info['min'], band_info['max'])
            
            # 应用状态权重
            amplitude = band_info['amplitude'] * state_weights.get(band_name, 1.0)
            
            # 生成正弦波
            wave = amplitude * math.sin(2 * math.pi * frequency * timestamp)
            signal += wave
        
        return signal
    
    def _get_state_weights(self, sleep_state: str) -> Dict[str, float]:
        """根据睡眠状态获取各频段权重（8个频域）"""
        weights = {
            'awake': {
                'delta': 0.3, 'theta': 0.5, 'low_alpha': 0.9, 'high_alpha': 1.1, 
                'low_beta': 1.2, 'high_beta': 1.0, 'low_gamma': 0.8, 'mid_gamma': 0.6
            },
            'light_sleep': {
                'delta': 0.8, 'theta': 1.0, 'low_alpha': 0.6, 'high_alpha': 0.5, 
                'low_beta': 0.4, 'high_beta': 0.3, 'low_gamma': 0.3, 'mid_gamma': 0.2
            },
            'deep_sleep': {
                'delta': 1.5, 'theta': 0.8, 'low_alpha': 0.3, 'high_alpha': 0.2, 
                'low_beta': 0.2, 'high_beta': 0.1, 'low_gamma': 0.1, 'mid_gamma': 0.1
            },
            'rem_sleep': {
                'delta': 0.6, 'theta': 1.2, 'low_alpha': 0.7, 'high_alpha': 0.6, 
                'low_beta': 0.9, 'high_beta': 0.7, 'low_gamma': 0.6, 'mid_gamma': 0.4
            }
        }
        return weights.get(sleep_state, weights['awake'])
    
    def _generate_power_spectrum(self) -> Dict[str, float]:
        """生成功率谱数据"""
        power_spectrum = {}
        
        for band_name, band_info in self.brain_wave_bands.items():
            # 模拟功率值（根据当前状态调整）
            base_power = random.uniform(10, 100)
            state_modifier = self._get_state_weights(self.current_sleep_state).get(band_name, 1.0)
            power_spectrum[band_name] = round(base_power * state_modifier, 2)
        
        return power_spectrum
    
    def _detect_sleep_state(self, power_spectrum: Dict[str, float]) -> str:
        """根据功率谱检测睡眠状态"""
        delta_power = power_spectrum.get('delta', 0)
        alpha_power = power_spectrum.get('alpha', 0)
        beta_power = power_spectrum.get('beta', 0)
        
        # 简单的状态检测逻辑
        if delta_power > 80:
            new_state = 'deep_sleep'
        elif delta_power > 50 and alpha_power < 30:
            new_state = 'light_sleep'
        elif beta_power > 60 and alpha_power > 40:
            new_state = 'awake'
        else:
            new_state = 'rem_sleep'
        
        # 状态变化有一定的惯性
        if random.random() < 0.8:  # 80%概率保持当前状态
            self.current_sleep_state = new_state
        
        return self.current_sleep_state
    
    def _calculate_sleep_quality(self, sleep_state: str, power_spectrum: Dict[str, float]) -> float:
        """计算睡眠质量评分"""
        base_scores = {
            'awake': 0.3,
            'light_sleep': 0.6,
            'deep_sleep': 0.9,
            'rem_sleep': 0.7
        }
        
        base_score = base_scores.get(sleep_state, 0.5)
        
        # 根据功率谱调整评分
        delta_ratio = power_spectrum.get('delta', 0) / 100
        noise_factor = 1 - (power_spectrum.get('gamma', 0) / 200)  # 高频噪声降低质量
        
        quality_score = base_score * (0.7 + 0.3 * delta_ratio) * max(0.5, noise_factor)
        
        return round(min(1.0, max(0.0, quality_score)), 3)
    
    def _get_dominant_frequency(self, power_spectrum: Dict[str, float]) -> float:
        """获取主导频率"""
        max_power = 0
        dominant_band = 'alpha'
        
        for band_name, power in power_spectrum.items():
            if power > max_power:
                max_power = power
                dominant_band = band_name
        
        # 返回该频段的中心频率
        band_info = self.brain_wave_bands[dominant_band]
        return round((band_info['min'] + band_info['max']) / 2, 1)
    
    def _calculate_checksum(self, value: float, timestamp: float) -> str:
        """计算数据校验和"""
        data_str = f"{value:.2f}_{timestamp:.3f}"
        return str(hash(data_str) % 10000).zfill(4)
    
    def _real_time_generation_loop(self):
        """实时数据生成循环"""
        interval = 1.0 / self.sampling_rate  # 采样间隔
        
        while self.is_generating:
            start_time = time.time()
            
            # 生成单个数据包
            data_packets = self.generate_raw_eeg_data(duration_seconds=interval)
            
            if data_packets and self.data_callback:
                # 同时生成过滤数据
                filtered_data = self.generate_filtered_data(data_packets)
                
                # 组合数据包
                combined_packet = {
                    'raw_data': data_packets[0],
                    'filtered_data': filtered_data[0] if filtered_data else None,
                    'timestamp': time.time()
                }
                
                self.data_callback(combined_packet)
            
            # 控制生成频率
            elapsed = time.time() - start_time
            sleep_time = max(0, interval - elapsed)
            if sleep_time > 0:
                time.sleep(sleep_time)
    
    def get_service_status(self) -> Dict[str, Any]:
        """获取服务状态"""
        return {
            'is_generating': self.is_generating,
            'sequence_counter': self.sequence_counter,
            'current_sleep_state': self.current_sleep_state,
            'sampling_rate': self.sampling_rate,
            'service_uptime': time.time()
        }


# 单例模式
_mock_data_service_instance = None

def get_mock_data_service() -> MockDataService:
    """获取模拟数据服务单例"""
    global _mock_data_service_instance
    if _mock_data_service_instance is None:
        _mock_data_service_instance = MockDataService()
    return _mock_data_service_instance